package com.im.app.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.im.app.manager.ConversationManager;
import com.im.app.mapper.ConversationsMapper;
import com.im.app.mapper.GroupMapper;
import com.im.app.mapper.IUserMapper;
import com.im.app.model.Conversations;
import com.im.app.model.User;
import com.im.app.service.ConversationsService;
import com.im.app.utils.Response;
import com.im.app.utils.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.jim.core.cache.redis.JedisTemplate;
import org.jim.core.packets.ChatType;
import org.jim.core.packets.Group;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class ConversationsServiceImpl  extends ServiceImpl<ConversationsMapper, Conversations> implements ConversationsService {

    @Resource
    private ConversationsMapper conversationsMapper;

    @Resource
    private IUserMapper userMapper;

    @Resource
    private GroupMapper groupMapper;

    @Override
    public int  insert(Conversations conversations) {
        int result = conversationsMapper.insert(conversations);
        ConversationManager.getManager().cacheConversation(conversations);
        return result;
    }

    @Override
    public Conversations selectByGroup(String ownerUserId, String groupId) {
        String key = "conversation_"+ownerUserId+"_"+groupId;
        Conversations conversations = ConversationManager.getManager().getConversation(key);
        if(conversations == null){
            conversations = conversationsMapper.selectByGroup(ownerUserId, groupId);
            if(conversations != null){
                ConversationManager.getManager().cacheConversation(conversations);
            }
        }
        return conversations;
    }

    @Override
    public List<Conversations> selectByGroupId(String groupId) {
        String key = "conversation_"+groupId;
        List<Conversations> conversations = ConversationManager.getManager().getGroupConversations(key);
        if(conversations == null){
            conversations = conversationsMapper.selectByGroupId(groupId);
            if(conversations != null){
                ConversationManager.getManager().cacheGroupConversation(conversations,groupId);
            }
        }
        return conversations;
    }


    @Override
    public Conversations selectByUser(String ownerUserId, String userId) {
        String key = "conversation_"+ownerUserId+"_"+userId;
        Conversations conversations = ConversationManager.getManager().getConversation(key);
        if(conversations == null){
            conversations = conversationsMapper.selectByUser(ownerUserId, userId);
            if(conversations != null){
                ConversationManager.getManager().cacheConversation(conversations);
            }
        }
        return conversations;
    }

    @Async
    @Override
    public void update(Conversations conversations) {
        ConversationManager.getManager().cacheConversation(conversations);
        conversationsMapper.updateById(conversations);
    }

    @Override
    public int updateCon(String userId,String nickName,String avatar) {
        return conversationsMapper.updateCon(userId,nickName,avatar);
    }

    @Override
    public void updateCacheGroup(List<Conversations> conversationsList,String groupId) {
        ConversationManager.getManager().cacheGroupConversation(conversationsList,groupId);
    }

    @Override
    public int updateIsPinned(Integer isPinned,String conversationId) {
        int result = conversationsMapper.updateIsPinned(isPinned,conversationId);
        if(result > 0){
            Conversations conversations = conversationsMapper.selectById(conversationId);
            ConversationManager.getManager().cacheConversation(conversations);
        }
        return result;
    }

    @Override
    public int updateIsBlack(Integer isBlack,String ownerUserId,String userId) {
        int result = conversationsMapper.updateIsBlack(isBlack,ownerUserId,userId);
        if(result > 0){
            Conversations conversations = conversationsMapper.selectByUser(ownerUserId, userId);
            ConversationManager.getManager().cacheConversation(conversations);
        }
        return result;
    }

    @Override
    public int updateNick(String nickName,String conversationId) {
        int result = conversationsMapper.updateNick(nickName,conversationId);
        if(result > 0){
            Conversations conversations = conversationsMapper.selectById(conversationId);
            ConversationManager.getManager().cacheConversation(conversations);
        }
        return result;
    }

    @Override
    public int clearUnreadCount(String conversationId) {
        int result = conversationsMapper.clearUnreadCount(conversationId);
        if(result > 0){
            Conversations conversations = conversationsMapper.selectById(conversationId);
            ConversationManager.getManager().cacheConversation(conversations);
        }
        return result;
    }

    @Override
    public List<Conversations> getConversationsList(String ownerUserId) {
        return conversationsMapper.getConversationsList(ownerUserId);
    }

    @Override
    public List<Conversations> getConversationByKeyWord(String ownerUserId,String keyWord) {
        return conversationsMapper.getConversationByKeyWord(ownerUserId,keyWord);
    }

    @Override
    public int clearConversations(String conversationId) {
        Conversations conversations = conversationsMapper.selectById(conversationId);
        if (conversations != null){
            ConversationManager.getManager().delCacheConversation(conversations);
            return conversationsMapper.clearConversations(conversationId);
        }
        return 0;
    }

    @Override
    public int clearByDays(String userId,Integer days) {
        List<Conversations> conversations = conversationsMapper.selectByDays(userId,days);
        int result = conversationsMapper.clearByDays(userId,days);
        for (Conversations conversation : conversations) {
            ConversationManager.getManager().delCacheConversation(conversation);
        }
        return result;
    }

    @Override
    public int clearByDaysOut(Integer days) {
        List<Conversations> conversations = conversationsMapper.selectByDaysOut(days);
        for (Conversations conversation : conversations) {
            ConversationManager.getManager().delCacheConversation(conversation);
        }
        return conversationsMapper.clearByDaysOut(days);
    }

    @Override
    public int clearByUserIdsOut(String ids) {
        String[] userIds = ids.split(",");
        for (String userId : userIds) {
            clearByDays(userId,-1);
        }
        return 0;
    }

    @Override
    public Conversations selectLastMessage(String conversationId) {
        return conversationsMapper.selectLastMessage(conversationId);
    }

    public ResponseResult<Object> createConversation(String ownerUserId, Integer type, String id){

        Conversations conversations = null;
        if(type == ChatType.CHAT_TYPE_PRIVATE.getNumber()){
            conversations = selectByUser(ownerUserId,id);
        }else if(type == ChatType.CHAT_TYPE_PUBLIC.getNumber()){
            conversations = selectByGroup(ownerUserId,id);
        }
        if(conversations != null){
            return Response.makeOKRsp().setData(conversations);
        }

        conversations = new Conversations();
        conversations.setOwnerUserId(ownerUserId);
        conversations.setIsPinned(0);
        conversations.setUnreadCount(0);
        if(type == ChatType.CHAT_TYPE_PRIVATE.getNumber()){
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.eq("user_id",id);
            User user1 = userMapper.selectOne(userQueryWrapper);
            if(user1 == null){
                return Response.makeErrRsp("用户不存在");
            }
            conversations.setNickName(user1.getName());
            conversations.setAvatar(user1.getAvatar());
            conversations.setUserId(id);
        }else if(type == ChatType.CHAT_TYPE_PUBLIC.getNumber()){
            Group group = groupMapper.selectGroupsByGroupId(id);
            if(group == null){
                return Response.makeErrRsp("群信不存在");
            }
            conversations.setNickName(group.getName());
            conversations.setAvatar(group.getAvatar());
            conversations.setGroupId(id);
        }else {
            return Response.makeErrRsp("会话类型有误");
        }
        conversations.setLastTime(new Date().getTime());
        conversations.setConversationType(type);
        if (insert(conversations) > 0){
            return Response.makeOKRsp().setData(conversations);
        }else {
            return Response.makeErrRsp("创建会话失败");
        }
    }
}

